/*
 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
 *
 * Copyright (C) 2016-2023 Philip Helger (www.helger.com)
 * philip[at]helger[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitee.wsl.coroutines.job.sheduler

import com.gitee.wsl.coroutines.job.exception.SchedulerException
import kotlin.time.Instant
import kotlin.reflect.KClass
import kotlin.time.ExperimentalTime

/**
 * Describes the settings and capabilities of a given
 * `[IScheduler]` instance.
 *
 * @author James House
 */
@OptIn(ExperimentalTime::class)
class SchedulerMetaData(
    /**
     * Returns the name of the `Scheduler`.
     */
    val schedulerName: String,
    /**
     * Returns the instance Id of the `Scheduler`.
     */
    val schedulerInstanceId: String,
    val schedulerClass:KClass<*>,
    val isStarted: Boolean,
    /**
     * Reports whether the `Scheduler` is in standby mode.
     */
    val isInStandbyMode: Boolean,
    val isShutdown: Boolean,
    val startTime: Instant?,
    val numberOfJobsExecuted: Int,
    val jobStoreClass:KClass<*>,
    val isJobStoreSupportsPersistence: Boolean,
    val isJobStoreClustered: Boolean,
    val threadPoolClass:KClass<*>,
    val threadPoolSize: Int,
    /**
     *
     *
     * Returns the version of Quartz that is running.
     *
     */
    val version: String
) {

    val runningSince: Instant?
        /**
         * Returns the `Date` at which the Scheduler started running.
         *
         * @return null if the scheduler has not been started.
         */
        get() = startTime


    /**
     *
     *
     * Return a simple string representation of this object.
     *
     */
    override fun toString(): String {
        return try {
            summary
        } catch (se: SchedulerException) {
            "SchedulerMetaData: undeterminable."
        }
    }

    @get:Throws(SchedulerException::class)
    val summary: String
        /**
         *
         *
         * Returns a formatted (human readable) String describing all the
         * `Scheduler`'s meta-data values.
         *
         *
         *
         * The format of the String looks something like this:
         *
         *
         * <pre>
         * Mini Quartz Scheduler 'SchedulerName' with instanceId 'SchedulerInstanceId' Scheduler class: 'com.helger.quartz.impl.StdScheduler' - running locally. Running since: '11:33am on Jul 19, 2002' Not currently paused. Number of Triggers fired: '123' Using thread pool 'com.helger.quartz.simpl.SimpleThreadPool' - with '8' threads Using job-store 'com.helger.quartz.impl.JDBCJobStore' - which supports persistence.
        </pre> *
         *
         * @throws SchedulerException
         * On error
         */
        get() {
            val aSB: StringBuilder = StringBuilder("Mini Quartz Scheduler (v")
            aSB.append(version)
            aSB.append(") '")

            aSB.append(schedulerName)
            aSB.append("' with instanceId '")
            aSB.append(schedulerInstanceId)
            aSB.append("'\n")

            aSB.append("  Scheduler class: '")
            aSB.append(schedulerClass.simpleName)
            aSB.append("'")
            aSB.append(" - running locally.")
            aSB.append("\n")

            if (!isShutdown) {
                if (runningSince != null) {
                    aSB.append("  Running since: ")
                    aSB.append(runningSince)
                } else {
                    aSB.append("  NOT STARTED.")
                }
                aSB.append("\n")

                if (isInStandbyMode) {
                    aSB.append("  Currently in standby mode.")
                } else {
                    aSB.append("  Not currently in standby mode.")
                }
            } else {
                aSB.append("  Scheduler has been SHUTDOWN.")
            }
            aSB.append("\n")

            aSB.append("  Number of jobs executed: ")
            aSB.append(numberOfJobsExecuted)
            aSB.append("\n")

            aSB.append("  Using thread pool '")
            aSB.append(threadPoolClass.simpleName)
            aSB.append("' - with ")
            aSB.append(threadPoolSize)
            aSB.append(" threads.")
            aSB.append("\n")

            aSB.append("  Using job-store '")
            aSB.append(jobStoreClass.simpleName)
            aSB.append("' - which ")
            if (isJobStoreSupportsPersistence) {
                aSB.append("supports persistence.")
            } else {
                aSB.append("does not support persistence.")
            }
            if (isJobStoreClustered) {
                aSB.append(" and is clustered.")
            } else {
                aSB.append(" and is not clustered.")
            }
            aSB.append("\n")

            return aSB.toString()
        }
}
